package org.example.annotation;

import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * @author : libo@juzishuke.com
 * @Title :
 * @Description :
 * @date : 2024/2/22 16:57
 * @since :1.0
 */
@Slf4j
@Aspect
@Configuration
public class RedisLockAspect {

    @Around(value = "@annotation(org.example.annotation.EnableRedisLock)")
    public void handleRedisLock(ProceedingJoinPoint joinPoint) throws Throwable {
        // 通过反射获取到注解对象，可见反射非常重要的
        EnableRedisLock redisLock = ((MethodSignature) joinPoint.getSignature()).getMethod()
                .getAnnotation(EnableRedisLock.class);
        log.info("handleRedisLock . {}", redisLock);
        // 获取注解对象的变量值
        String lockKey = redisLock.lockKey();
        long expireTime = redisLock.expireTime();
        TimeUnit timeUnit = redisLock.timeUnit();
        int retryTimes = redisLock.retryTimes();

        // 获取锁
        if (tryLock(lockKey, expireTime, timeUnit, retryTimes)) {
            try {
                // 获取锁成功继续执行业务逻辑
                joinPoint.proceed();
            } finally {
                releseLock();
            }
        }
    }

    private void releseLock() {
        log.info("release lock ");
    }

    private boolean tryLock(String lockKey, long expireTime, TimeUnit timeUnit, int retryTimes) {
        log.info("start lock ", lockKey);
        return true;
    }
}
